/***************************************************************************
 *   Copyright (C) 2009 by maarten,,,   *
 *   maarten@maarten-laptop   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "scenemanager.h"

#include <QFile>
#include <qxml.h>
#include <QString>
#include "parser/parser.h" 
#include "scenemanager/sceneelement.h"
#include "scenemanager/camera/camera.h"
#include "scenemanager/scene/scene.h"
#include "scenemanager/scene/subscene.h"

#include <iostream>
using namespace std;

#include "objects/objectlist.h"

using namespace object;

namespace scene {

SceneManager::SceneManager()
{
    m_playScene = -1;
    m_objectList = new ObjectList();
    m_status = -1; // not loaded
}


SceneManager::~SceneManager()
{
    for(int i = 0; i < m_sceneElements.size(); ++i)
        delete m_sceneElements[i];

    for(int i = 0; i < m_scenes.size(); ++i)
        delete m_scenes[i];

    for(int i = 0; i < m_lights.size(); ++i)
        delete m_lights[i];
    
    if(m_objectList != NULL)
      delete m_objectList;
}

void SceneManager::loadScene(QString temp)
{
    QFile newFile(temp );
    parser::Parser *newParser = new parser::Parser(this);
    QXmlInputSource source ( (QIODevice*)&newFile );
    QXmlSimpleReader reader;
    reader.setContentHandler( newParser );
    m_status = 1; // set to succes
    reader.parse(source); // can put status to failure
    delete newParser;
    
}

void SceneManager::clear()
{
    cout << "deleting sceneelements\n";
    for(int i = 0; i < m_sceneElements.size(); ++i)
        delete m_sceneElements[i];
    
    m_sceneElements.clear();

    cout << "deleting scenes...\n";
    for(int i = 0; i < m_scenes.size(); ++i)
        delete m_scenes[i];
    
    m_scenes.clear();

    cout << "deleting lights...\n";
    for(int i = 0; i < m_lights.size(); ++i)
        delete m_lights[i];
    
    m_lights.clear();
    
    cout << "cleaning objectlist \n";
    m_objectList->clean();
    
    cout << "deleting geometries\n";
    for(int i = 0; i < m_geometries.size(); ++i)
        delete m_geometries[i];
    
    m_geometries.clear();
    
    cout << "deleting materials\n";
    for(int i = 0; i < m_materials.size(); ++i)
        delete m_materials[i];
    
    m_materials.clear();
    
    cout << "deleting textures\n";
    for(int i = 0; i < m_textures.size(); ++i)
        delete m_textures[i];
    
    m_textures.clear();
    
    m_playScene = -1;
}

bool SceneManager::loadObject(QString name)
{
    return m_objectList->loadObject(name);
}

void SceneManager::addSceneElement(SceneElement *sel)
{
    m_sceneElements.push_back(sel);
    
}

void SceneManager::addSubScene(SubScene *sel)
{
  
}

void SceneManager::addCamera(SceneElement *sel)
{
    m_cameras.push_back(sel);
}

void SceneManager::addLight(SceneElement *sel)
{
    //check if surfacelight
    // => then add all little lights    
    m_lights.push_back(sel);
}

void SceneManager::addSurfaceLight(QString tempName)
{
    m_surfaceLights.push_back(tempName);
}

void SceneManager::addScene(SceneElement *sel)
{
    m_scenes.push_back(sel);
    m_playScene = 0;
}

void SceneManager::addGeometry(SceneElement *sel)
{
    m_geometries.push_back(sel);
}

void SceneManager::addMaterial(SceneElement *sel)
{
  m_materials.push_back(sel);
}

void SceneManager::addTexture(SceneElement *sel)
{
  m_textures.push_back(sel);
}

Camera* SceneManager::getCamera(QString camName)
{
    for(int i = 0; i < m_cameras.size(); ++i)
        if(m_cameras[i]->name().compare(camName) == 0)
            return (Camera*)m_cameras[i];

    return NULL;
}

bool SceneManager::isSurfaceLight(QString tempName)
{
  for(int i = 0; i < m_surfaceLights.size(); ++i)
    if(m_surfaceLights.at(i).compare(tempName) == 0)
      return true;
    
  return false;
}

SceneElement* SceneManager::getLight(QString lightName)
{
    for(int i = 0; i < m_lights.size(); ++i)
        if(m_lights[i]->name().compare(lightName) == 0)
            return m_lights[i];

    cout << "ERROR: LIGHT NOT FOUND: -" << lightName.toStdString() << "- , " <<
             "\n";
    return NULL;
}

/* TODO Not possible to get more then one scene... app will fail */
Scene* SceneManager::getScene()
{
    if(m_playScene != -1)
        return (Scene*)m_scenes[m_playScene];

    return NULL;
}

/* TODO Not possible to get more then one scene... app will fail */
SceneElement* SceneManager::getGeometry(QString name)
{
    for(int i = 0; i < m_geometries.size(); ++i)
        if(m_geometries[i]->name().compare(name) == 0)
            return m_geometries[i];

    return NULL;
}

SceneElement* SceneManager::getMaterial(QString name)
{
    for(int i = 0; i < m_materials.size(); ++i)
        if(m_materials[i]->name().compare(name) == 0)
            return m_materials[i];

    return NULL;  
}

SceneElement* SceneManager::getTexture(QString name)
{
    for(int i = 0; i < m_textures.size(); ++i)
        if(m_textures[i]->name().compare(name) == 0)
            return m_textures[i];

    return NULL;  
}

void SceneManager::printAllElements()
{
    cout << "printing scenemanager: \n";
    for(int i = 0; i < m_sceneElements.size(); ++i){
       m_sceneElements[i]->printElement();
    }     

    cout << "printing cams:\n";
    for(int i = 0; i < m_cameras.size(); ++i){
       m_cameras[i]->printElement();
    }      

    cout << "printing lights:\n";
    for(int i = 0; i < m_lights.size(); ++i){
       m_lights[i]->printElement();
    }  
    
    cout << "printing materials:\n";
    for(int i = 0; i < m_materials.size(); ++i){
       m_materials[i]->printElement();
    }
    cout << "printing textures:\n";
    for(int i = 0; i < m_textures.size(); ++i){
       m_textures[i]->printElement();
    }  
    
    cout << "printing scenes: aantal:"<< m_scenes.size() <<"\n";
    for(int i = 0; i < m_scenes.size(); ++i){
       m_scenes[i]->printElement();
    }  
    
    cout << "Done printing scenemanager\:n";
}


}// end namespace scene
